using Microsoft.AspNetCore.Mvc;
using SumerCoreDevOps.Infrastructure.Scheduling;

namespace SumerCoreDevOps.ControlApi.Controllers;

/// <summary>
/// 节点发现控制器（用于执行节点发现主节点）
/// </summary>
[ApiController]
[Route("api/node")]
public class NodeDiscoveryController : ControllerBase
{
    private readonly ILogger<NodeDiscoveryController> _logger;
    private readonly IConfiguration _configuration;

    public NodeDiscoveryController(
        ILogger<NodeDiscoveryController> logger,
        IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
    }

    /// <summary>
    /// 发现可用的主节点
    /// </summary>
    /// <remarks>
    /// 执行节点通过此接口发现所有可用的主节点信息，然后建立 TCP 连接
    /// </remarks>
    /// <returns>返回节点发现响应对象,包含当前主节点信息(主节点ID、主机、TCP端口、API端口等)和所有可用主节点列表;如果启用了分布式模式则返回多个在线主节点,否则只返回当前主节点;数据封装在ApiResponse对象中;发生错误时返回500状态码和失败信息</returns>
    [HttpGet("discover")]
    [ProducesResponseType(typeof(ApiResponse<NodeDiscoveryResponse>), 200)]
    public async Task<IActionResult> Discover()
    {
        try
        {
            var tcpPort = _configuration.GetValue<int>("TcpServer:Port", 9090);
            var currentHost = _configuration.GetValue<string>("Hosting:Host") ?? Request.Host.Host;
            var enableDistributed = _configuration.GetValue<bool>("Distributed:Enabled", false);

            var response = new NodeDiscoveryResponse
            {
                CurrentMaster = new MasterNodeInfo
                {
                    MasterId = $"{currentHost}:{tcpPort}",
                    Host = currentHost,
                    TcpPort = tcpPort,
                    ApiPort = _configuration.GetValue<int>("Hosting:Port", 5000),
                    IsDistributed = enableDistributed
                },
                AvailableMasters = new List<MasterNodeInfo>()
            };

            // 如果启用了分布式模式，尝试从数据库获取所有在线主节点
            if (enableDistributed)
            {
                try
                {
                    var masterNodeManager = HttpContext.RequestServices.GetService<MasterNodeManager>();
                    if (masterNodeManager != null)
                    {
                        var onlineMasters = await masterNodeManager.GetOnlineMastersAsync();
                        response.AvailableMasters = onlineMasters.Select(m => new MasterNodeInfo
                        {
                            MasterId = m.MasterId,
                            Host = m.Host,
                            TcpPort = m.TcpPort,
                            ApiPort = m.ApiPort,
                            IsDistributed = true,
                            LastHeartbeat = m.LastHeartbeat
                        }).ToList();

                        _logger.LogInformation("发现请求: 返回 {Count} 个在线主节点", response.AvailableMasters.Count);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "无法获取其他主节点信息，仅返回当前主节点");
                }
            }

            // 如果没有获取到其他主节点，至少返回当前主节点
            if (response.AvailableMasters.Count == 0)
            {
                response.AvailableMasters.Add(response.CurrentMaster);
            }

            return Ok(new ApiResponse<NodeDiscoveryResponse>
            {
                Success = true,
                Data = response,
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "节点发现失败");
            return StatusCode(500, new ApiResponse<object>
            {
                Success = false,
                ErrorMessage = "节点发现失败",
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
            });
        }
    }

    /// <summary>
    /// 健康检查（用于验证主节点是否可访问）
    /// </summary>
    /// <returns>返回健康状态对象,包含status状态字符串(值为"healthy")和timestamp时间戳;用于执行节点验证主节点的可用性</returns>
    [HttpGet("health")]
    public IActionResult Health()
    {
        return Ok(new
        {
            status = "healthy",
            timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
        });
    }
}

/// <summary>
/// 节点发现响应
/// </summary>
public class NodeDiscoveryResponse
{
    /// <summary>
    /// 当前主节点信息
    /// </summary>
    public MasterNodeInfo CurrentMaster { get; set; } = null!;

    /// <summary>
    /// 所有可用主节点列表
    /// </summary>
    public List<MasterNodeInfo> AvailableMasters { get; set; } = new();
}

/// <summary>
/// 主节点信息
/// </summary>
public class MasterNodeInfo
{
    /// <summary>
    /// 主节点ID
    /// </summary>
    public string MasterId { get; set; } = string.Empty;

    /// <summary>
    /// 主机名或IP
    /// </summary>
    public string Host { get; set; } = string.Empty;

    /// <summary>
    /// TCP 端口
    /// </summary>
    public int TcpPort { get; set; }

    /// <summary>
    /// API 端口
    /// </summary>
    public int ApiPort { get; set; }

    /// <summary>
    /// 是否启用分布式模式
    /// </summary>
    public bool IsDistributed { get; set; }

    /// <summary>
    /// 最后心跳时间
    /// </summary>
    public DateTime? LastHeartbeat { get; set; }
}

/// <summary>
/// API 响应包装类
/// </summary>
public class ApiResponse<T>
{
    public bool Success { get; set; }
    public T? Data { get; set; }
    public string? ErrorMessage { get; set; }
    public long Timestamp { get; set; }
}
